﻿using System;
using System.Collections.Generic;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Media;

using TinyLib.Input;

namespace TinyLib.Audio
{
    public class MusicManager : GameComponent
    {
        #region Fields

        float fMusicVolume = 0.1f;
        private Dictionary<string, SoundEffect> _sounds = new Dictionary<string, SoundEffect>();

        private SoundEffectInstance[] _playingSounds = new SoundEffectInstance[32];
        private SoundEffectInstance[] _loopingSounds = new SoundEffectInstance[32];
        private SoundEffectInstance[] _playList = new SoundEffectInstance[32];
        private SoundEffectInstance[] _musicList = new SoundEffectInstance[32];

        int lastListSong = 32, listnr = 0, musicListSpot = 31;
        bool playListStart = false, random, musicListStart;
        List<string> musicListString = new List<string>();

        //float soundVolume = 0.5f;

        #endregion

        #region Properties
        #endregion

        #region Inits

        public MusicManager(Game game)
            : base(game)
        {
        }

        public override void Initialize()
        {
            IniFile configFile = new IniFile("textRef\\Values.ini");
            configFile.Parse();

            // fMusicVolume = float.Parse( configFile.GetValue("Music", "MusicVolume") );
            fMusicVolume = 0.5f;
        }

        #endregion

        #region Various Functions

        public void LoadSound(string soundName)
        {
            LoadSound(soundName, "Audio//Music//" + soundName);
        }

        public void LoadSound(string soundName, string soundPath)
        {
            if (_sounds.ContainsKey(soundName))
            {
                throw new InvalidOperationException(string.Format("Sound '{0}' has already been loaded", soundName));
            }

            _sounds.Add(soundName, Game.Content.Load<SoundEffect>(soundPath));
        }

        public override void Update(GameTime gameTime)
        {
            for (int i = 0; i < _playingSounds.Length; ++i)
            {
                if (_playingSounds[i] != null && _playingSounds[i].State == SoundState.Stopped)
                {
                    _playingSounds[i].Dispose();
                    _playingSounds[i] = null;
                }
            }

            for (int i = 0; i < _loopingSounds.Length; ++i)
            {
                if (_loopingSounds[i] != null && _loopingSounds[i].State == SoundState.Stopped)
                {
                    _loopingSounds[i].Play();
                }
            }

            if (musicListStart)
            {
                bool newSong = true;
                for (int i = 0; i < _playList.Length; ++i)
                {
                    if (_playList[i] != null && _playList[i].State == SoundState.Stopped)
                    { }
                    else if (_playList[i] != null)
                    { newSong = false; }
                }

                if (newSong == true)
                {
                    musicList(null);
                }
            }

            if (playListStart)
            {
                bool newSong = true;
                for (int i = 0; i < _playList.Length; ++i)
                {
                    if (_playList[i] != null && _playList[i].State == SoundState.Stopped)
                    { }
                    else if (_playList[i] != null)
                    { newSong = false; }
                }

                if (newSong == true)
                {
                    if (random == true) playListrnd();
                    if (random == false) playList();
                }
            }

            base.Update(gameTime);
        }

        public void playList()
        {
            playListStart = true;
            int newListSong = lastListSong - 1;
            if (newListSong < _playList.Length - listnr)
            {
                newListSong = 31;
            }
            _playList[newListSong].Play();
            lastListSong = newListSong;
        }

        public void playListrnd()
        {
            playListStart = true;
            int dice;
            do
            {
                Random rnd = new Random();
                dice = rnd.Next(29, 31);
            }
            while (dice == lastListSong || lastListSong == 0);
            _playList[dice].Play();
            lastListSong = dice;
        }

        #endregion

        #region Music List

        public void musicList(string newSong)
        {
            int o = 0;
            foreach (String boop in musicListString)
            {
                if (_musicList[31 - o].State == SoundState.Playing)
                {
                    if (newSong == musicListString[31 - musicListSpot] || newSong == null)
                        return;
                }
                ++o;
            }

            if (newSong != null)
            {
                int tempo;
                tempo = 0 - musicListSpot;
                tempo = tempo + 31;

                for (int i = 0; i < _musicList.Length; ++i)
                {
                    if (_musicList[i] != null)
                        _musicList[i].Stop();
                }

                if (newSong == "stop")
                    return;

                o = 32;
                //                for (int i = 0; i < musicListString.LastIndexOf; ++i)
                foreach (String boop in musicListString)
                {
                    o = o - 1;
                    if (boop == newSong)
                    {
                        _musicList[o].Play();
                        musicListSpot = o;
                    }
                }
            }
            else if (newSong == null)
            {
                _musicList[musicListSpot].Play();
            }
        }

        public void addMusicListSound(string soundName)
        {
            MusicListSound(soundName, "Audio//Music//" + soundName);
        }

        public void MusicListSound(string soundName, string soundPath)
        {
            if (_sounds.ContainsKey(soundName)) { }
            else _sounds.Add(soundName, Game.Content.Load<SoundEffect>(soundPath));

            int listindex = 0;

            SoundEffect sound;

            if (!_sounds.TryGetValue(soundName, out sound))
            {
                throw new ArgumentException(string.Format("Sound '{0}' not found", soundName));
            }

            for (int i = 0; i < _musicList.Length; ++i)
            {
                if (_musicList[i] == null)
                {
                    listindex = i;
                }
            }

            // soundVolume = float.Parse(config.getValue("Options", "Music"));

            //soundVolume = 0.8f;

            _musicList[listindex] = sound.CreateInstance();
            //ÄNDRA NEDANSTÅENDE FÖR ATT ÄNDRA MUSIKVOLYM // TA EV IN VARIABLER FÖR ATT KONTROLLERA INDIVIDUELLA STYCKEN HÄR
            _musicList[listindex].Volume = 0.15f;
            _musicList[listindex].Pitch = 0.0f;
            _musicList[listindex].Pan = 0.0f;

            musicListString.Add(soundName);
        }

        #endregion

        #region Music effects

        public void MusicFade()
        {
        }

        public void MusicTuneUp()
        {
        }

        #endregion

    }
}
